<template>
	<n-collapse-item title="基础事件配置" name="2">
		<template #header-extra>
			<n-button type="primary" tertiary size="small" @click.stop="showModal = true">
				<template #icon>
					<n-icon>
						<pencil />
					</n-icon>
				</template>
				编辑
			</n-button>
		</template>
		<n-card class="collapse-show-box">
			<!-- 函数体 -->
			<div v-for="(value, key) in EventTypeName" :key="key">
				<p>
					<span class="func-annotate">// {{ value }}</span>
					<br />
					<span class="func-keyword">async {{ key }}</span> (e, componentList, callBack) {
				</p>
				<p class="go-ml-4">
					<n-code :code="(baseEvent || {})[key] || ''" language="javascript"></n-code>
				</p>
				<p>}<span>,</span></p>
			</div>
		</n-card>
	</n-collapse-item>

	<!-- 弹窗 -->
	<n-modal class="go-chart-data-monaco-editor" v-model:show="showModal" :mask-closable="false">
		<n-card :bordered="false" role="dialog" size="small" aria-modal="true" style="width: 1200px; height: 700px">
			<template #header>
				<n-text>基础事件编辑器</n-text>
			</template>
			<n-layout has-sider sider-placement="right">
				<n-layout style="height: 580px; padding-right: 20px">
					<n-tabs v-model:value="editTab" type="card" tab-style="min-width: 100px;">
						<n-tab-pane v-for="(value, key) in EventTypeName" :key="key" :tab="`${value}-${key}`" :name="key">
							<!-- 函数名称 -->
							<p class="p-l-5">
								<span class="func-keyword">async function &nbsp;&nbsp;</span>
								<span class="func-keyNameWord">{{ key }}(e, componentList, callBack)&nbsp;&nbsp;{</span>
							</p>
							<!-- 编辑主体 -->
							<my-monaco-editor v-model:modelValue="baseEvent[key]" height="480px" language="javascript" />
							<!-- 函数结束 -->
							<p class="p-l-5 func-keyNameWord">}</p>
						</n-tab-pane>
					</n-tabs>
				</n-layout>
				<n-layout-sider
					:collapsed-width="14"
					:width="340"
					show-trigger="bar"
					collapse-mode="transform"
					content-style="padding: 12px 12px 0px 12px;margin-left: 3px;"
				>
					<n-tabs default-value="1" justify-content="space-evenly" type="segment">
						<!-- 验证结果 -->
						<n-tab-pane tab="验证结果" name="1" size="small">
							<n-scrollbar trigger="none" style="max-height: 505px">
								<n-collapse class="go-px-3" arrow-placement="right" :default-expanded-names="[1, 2, 3]">
									<template v-for="error in [validEvents()]" :key="error">
										<n-collapse-item title="错误函数" :name="1">
											<n-text depth="3">{{ error.errorFn || '暂无' }}</n-text>
										</n-collapse-item>
										<n-collapse-item title="错误信息" :name="2">
											<n-text depth="3">{{ error.name || '暂无' }}</n-text>
										</n-collapse-item>
										<n-collapse-item title="堆栈信息" :name="3">
											<n-text depth="3">{{ error.message || '暂无' }}</n-text>
										</n-collapse-item>
									</template>
								</n-collapse>
							</n-scrollbar>
						</n-tab-pane>
					</n-tabs>
				</n-layout-sider>
			</n-layout>
			<template #action>
				<n-space justify="space-between">
					<div class="flex s-center">
						<n-tag :bordered="false" type="primary">
							<template #icon>
								<my-icon icon="DocumentText" />
							</template>
							说明
						</n-tag>
						<n-text class="m-l-5" depth="2">编写方式同正常 JavaScript 写法</n-text>
					</div>
					<n-space>
						<n-button size="medium" @click="closeEvents">取消</n-button>
						<n-button size="medium" type="primary" @click="saveEvents">保存</n-button>
					</n-space>
				</n-space>
			</template>
		</n-card>
	</n-modal>
</template>

<script setup>
const EventTypeName = {
	click: '单击',
	dblclick: '双击',
	mouseenter: '鼠标移入',
	mouseleave: '鼠标移出'
};

// 受控弹窗
const showModal = ref(false),
	// 编辑区域控制
	editTab = ref('click'),
	// 事件错误标识
	errorFlag = ref(false);

// events 函数模板
let baseEvent = ref({ ...$store.chart.getTargetData.orgConfig.events.baseEvent });

// 验证语法
function validEvents() {
	let errorFn = '';
	let message = '';
	let name = '';

	errorFlag.value = Object.entries(baseEvent.value).every(([eventName, str]) => {
		try {
			// 支持await，验证语法
			const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor;
			new AsyncFunction(str);
			return true;
		} catch (error) {
			message = error.message;
			name = error.name;
			errorFn = eventName;
			return false;
		}
	});
	return {
		errorFn,
		message,
		name
	};
}

// 关闭事件
function closeEvents() {
	showModal.value = false;
}

// 新增事件
function saveEvents() {
	if (validEvents().errorFn) {
		msgError('事件函数错误，无法进行保存');
		return;
	}
	if (Object.values(baseEvent.value).join('').trim() === '') {
		// 清空事件
		$store.chart.getTargetData.orgConfig.events.baseEvent = {
			click: undefined,
			dblclick: undefined,
			mouseenter: undefined,
			mouseleave: undefined
		};
	} else {
		$store.chart.getTargetData.orgConfig.events.baseEvent = { ...baseEvent.value };
	}
	closeEvents();
}
</script>
